#ifndef __DSTH_LOG_H__
#define __DSTH_LOG_H__

#include <cstdarg>
#include <stdlib.h> // for abort

//4996 '_snprintf' not safe
#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif

namespace dsth {

class Logger {
public:
    enum LogLevel {
        E_TRACE,
        E_DEBUG,
        E_INFO,
        E_WARN,
        E_ERROR,
        E_FATAL,
        NUM_LOG_LEVELS,
    };
    Logger() {}
    virtual ~Logger() {}
    virtual void Logv(const char* prestr, const char* format, va_list ap) = 0;

private:
    Logger(const Logger&);
    void operator=(const Logger&);
};

extern void NewLogger(const char* file, Logger::LogLevel level);
extern void NewLogger(const char* file, Logger::LogLevel level, int log_size_m, int rotate);
extern void Log(Logger::LogLevel level, const char* prestr, const char* format, ...);
extern Logger* kLogger;
extern long kMaxLogSize;
extern int kMaxRotate;

#define LOG_TRACE(format, ...) Log(Logger::E_TRACE, "TRACE", format, ## __VA_ARGS__);
#define LOG_DEBUG(format, ...) Log(Logger::E_DEBUG, "DEBUG", format, ## __VA_ARGS__);
#define LOG_INFO(format, ...)  Log(Logger::E_INFO,  "INFO",  format, ## __VA_ARGS__);
#define LOG_WARN(format, ...)  Log(Logger::E_WARN,  "WARN",  format, ## __VA_ARGS__);
#define LOG_ERROR(format, ...) Log(Logger::E_ERROR, "ERROR", format, ## __VA_ARGS__);
#define LOG_FATAL(format, ...) Log(Logger::E_FATAL, "FATAL", format, ## __VA_ARGS__); abort();

} //namespace
#endif // __DSTH_LOG_H__
